package com.ys.nms.module.business.service.vlans;

import cn.hutool.core.collection.CollUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ys.nms.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.ys.nms.module.business.dal.dataobject.ports.PortsDO;
import com.ys.nms.module.business.dal.dataobject.portsVlans.PortsVlansDO;
import com.ys.nms.module.business.dal.mysql.portsVlans.PortsVlansMapper;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import com.ys.nms.module.business.controller.admin.vlans.vo.*;
import com.ys.nms.module.business.dal.dataobject.vlans.VlansDO;
import com.ys.nms.framework.common.pojo.PageResult;
import com.ys.nms.framework.common.pojo.PageParam;
import com.ys.nms.framework.common.util.object.BeanUtils;

import com.ys.nms.module.business.dal.mysql.vlans.VlansMapper;

import static com.ys.nms.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.ys.nms.framework.common.util.collection.CollectionUtils.convertList;
import static com.ys.nms.framework.common.util.collection.CollectionUtils.diffList;
import static com.ys.nms.module.business.enums.ErrorCodeConstants.*;

/**
 * vlans Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
public class VlansServiceImpl implements VlansService {

    @Resource
    private VlansMapper vlansMapper;

    @Resource
    private PortsVlansMapper portsVlansMapper;

    @Override
    public Integer createVlans(VlansSaveReqVO createReqVO) {
        // 插入
        VlansDO vlans = BeanUtils.toBean(createReqVO, VlansDO.class);
        vlansMapper.insert(vlans);

        // 返回
        return vlans.getVlanId();
    }

    @Override
    public void updateVlans(VlansSaveReqVO updateReqVO) {
        // 校验存在
        validateVlansExists(updateReqVO.getVlanVlan());
        // 更新
        VlansDO updateObj = BeanUtils.toBean(updateReqVO, VlansDO.class);
        vlansMapper.updateById(updateObj);
    }

    @Override
    public void deleteVlans(Integer id) {
        // 校验存在
        validateVlansExists(id);
        // 删除
        vlansMapper.deleteById(id);
    }

    @Override
    public void deleteVlansListByIds(List<Integer> ids) {
        // 删除
        vlansMapper.deleteByIds(ids);
    }


    private void validateVlansExists(Integer id) {
        if (vlansMapper.selectById(id) == null) {
            throw exception(VLANS_NOT_EXISTS);
        }
    }

    @Override
    public VlansDO getVlans(Integer id) {
        return vlansMapper.selectById(id);
    }

    @Override
    public PageResult<VlansDO> getVlansPage(VlansPageReqVO pageReqVO) {
        PageResult<VlansDO> vlanList = vlansMapper.selectPage(pageReqVO);
        List<VlansDO> list = vlanList.getList();
        Integer deviceId = pageReqVO.getDeviceId();
        for (VlansDO vlansDO : list) {
            //vlan中的vlan对应portsVlan中的vlanVlan
            Integer vlanVlan = vlansDO.getVlanVlan();
            LambdaQueryWrapperX<PortsVlansDO> portsVlanWrapper = new LambdaQueryWrapperX<>();
            portsVlanWrapper.eq(PortsVlansDO::getDeviceId, deviceId);
            portsVlanWrapper.eq(PortsVlansDO::getVlan, vlanVlan);
            List<PortsVlansDO> portsVlansDOS = portsVlansMapper.selectList(portsVlanWrapper);
            List<PortsVlansDO> uptList = portsVlansMapper.selectJoinList(PortsVlansDO.class, new MPJLambdaWrapper<PortsVlansDO>()
                    .selectAll(PortsVlansDO.class)
                    .selectAssociation(PortsDO.class, PortsVlansDO::getPortsDO)
                    .eq(PortsVlansDO::getDeviceId, deviceId)
                    .eq(PortsVlansDO::getVlan, vlanVlan)
                    .leftJoin(PortsDO.class, PortsDO::getPortId, PortsVlansDO::getPortId)
                    .eq(PortsDO::getIfOperStatus, "up")
            );

            List<PortsVlansDO> downtList = portsVlansMapper.selectJoinList(PortsVlansDO.class, new MPJLambdaWrapper<PortsVlansDO>()
                    .selectAll(PortsVlansDO.class)
                    .selectAssociation(PortsDO.class, PortsVlansDO::getPortsDO)
                    .eq(PortsVlansDO::getDeviceId, deviceId)
                    .eq(PortsVlansDO::getVlan, vlanVlan)
                    .leftJoin(PortsDO.class, PortsDO::getPortId, PortsVlansDO::getPortId)
                    .eq(PortsDO::getIfOperStatus, "down")
            );
            StringJoiner upJoiner = new StringJoiner(",");
            StringJoiner downJoiner = new StringJoiner(",");

            for (PortsVlansDO portsVlansDO : uptList) {
                upJoiner.add(portsVlansDO.getPortsDO().getIfName());
            }

            for (PortsVlansDO portsVlansDO : downtList) {
                downJoiner.add(portsVlansDO.getPortsDO().getIfName());
            }

            vlansDO.setUpString(upJoiner.toString());   // 自动用逗号分隔，无尾部逗号
            vlansDO.setDownString(downJoiner.toString());


        }

        return vlanList;
    }

}